﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Lucene.Linq.Search;

namespace Lucene.Linq.VSTests
{
    [TestClass]
    public class TestSearching
    {
        #region Indexers and Generators

        private readonly Action<Index<Sample>, int> IndexSamples = (idx, num) =>
                                                                       {
                                                                           idx.Add(SampleGenerator.GetRandom(num));
                                                                           Assert.IsTrue(idx.Count == num);
                                                                       };

        private readonly Func<Index<Sample>, int, int, IEnumerable<Sample>> IndexSamplesAndTake =
            (idx, num, returnResult) =>
            {
                Sample[] items = SampleGenerator.GetRandom(num).ToArray();
                idx.Add(items);
                Assert.IsTrue(idx.Count == num);
                return items.Take(returnResult);
            };

        private readonly Func<Index<Sample>, int, Sample> IndexSamplesAndTakeFirst = (idx, num) =>
                                                                                         {
                                                                                             Sample first =
                                                                                                 SampleGenerator.
                                                                                                     GetRandom(1).First();
                                                                                             Sample second =
                                                                                                 SampleGenerator.
                                                                                                     GetRandom(1).First();
                                                                                             Sample third =
                                                                                                 SampleGenerator.
                                                                                                     GetRandom(1).First();


                                                                                             idx.Add(first);
                                                                                             idx.Add(second);
                                                                                             idx.Add(third);
                                                                                             Console.WriteLine(
                                                                                                 "index count: {0}",
                                                                                                 idx.Count);
                                                                                             Assert.IsTrue(idx.Count ==
                                                                                                           3);

                                                                                             idx.Delete(0);
                                                                                             idx.Delete(1);
                                                                                             Assert.IsTrue(idx.Count ==
                                                                                                           1);

                                                                                             // add the number of samples, minus the one we've already added
                                                                                             idx.Add(
                                                                                                 SampleGenerator.
                                                                                                     GetRandom(num - 1));

                                                                                             return third;
                                                                                         };

        #endregion

        [TestMethod]
        public void Calling_ToList_On_Index_Should_Return_All_Documents()
        {
            using (var i = new Index<Sample>())
            {
                IEnumerable<Sample> all = IndexSamplesAndTake(i, 10, 10);
                List<Sample> results = i.ToList();

                Assert.IsTrue(all.OrderBy(t => t).SequenceEqual(results.OrderBy(t => t)));
                //Assert.AreEqual(all, results, (a, b) => a == b);
            }
        }

        [TestMethod]
        public void No_Where_Clause_Should_Return_Whole_Index_Set()
        {
            using (var i = new Index<Sample>())
            {
                IEnumerable<Sample> all = IndexSamplesAndTake(i, 10, 10);

                IQueryable<Sample> results = from s in i
                                             select s;

                Assert.IsTrue(all.SequenceEqual(results));
            }
        }


        [TestMethod]
        public void String_Equality_With_Variable()
        {
            using (var i = new Index<Sample>())
            {
                Sample firstItem = IndexSamplesAndTakeFirst(i, 10);

                IQueryable<Sample> results = from s in i
                                             where s.MrString == firstItem.MrString
                                             select s;

                Assert.AreEqual(results.Count(), 1);
                Assert.AreEqual(results.ElementAt(0).MrString, firstItem.MrString);
                //Assert.Inconclusive("Must be fixed");
            }
        }

        [TestMethod]
        public void String_Equality_With_Literal()
        {
            using (var i = new Index<Sample>())
            {
                i.Add(new Sample
                          {
                              BobDoublina = 10.0d,
                              SargeantInteger = 10.223f,
                              CaptainInteger = 100,
                              MrString = "blah blah"
                          });

                IQueryable<Sample> results = from s in i
                                             where s.MrString == "blah blah"
                                             select s;

                Assert.AreEqual(results.Count(), 1);
                Assert.AreEqual(results.ElementAt(0).MrString, "blah blah");
            }
        }
    }
}